﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using VOL.Entity.DomainModels;
using VOL.SmartHealthcare.Infrastructure;
using VOL.Team.Comm;

namespace VOL.Team.TeamIServices.Device_Management
{
    /// <summary>
    /// 设备台账实现接口
    /// </summary>
    public class EquipmentLedgerService : IEquipmentLedgerService
    {
        /// <summary>
        /// 设备台账仓储接口
        /// </summary>
        private readonly IBaseRepository<EquipmentLedger> baseRepository;

        /// <summary>
        /// 设备台账服务构造函数
        /// </summary>
        /// <param name="baseRepository">设备台账仓储接口</param>
        public EquipmentLedgerService(IBaseRepository<EquipmentLedger> baseRepository)
        {
            this.baseRepository = baseRepository;
        }

        /// <summary>
        /// 查询设备台账列表，支持分页和条件查询
        /// </summary>
        /// <param name="query">请求</param>
        /// <returns>返回分页结果</returns>
        public APIPaging<EquipmentLedger> EquipmentLedgerQuery(Query_Condition_EL query)
        {
            var queryable = baseRepository.GetAll()
               .Where(e => string.IsNullOrEmpty(query.EquipmentName) || e.EquipmentName.Contains(query.EquipmentName));
            var totalCount = queryable.Count();
            var data = queryable
               .OrderByDescending(e => e.EquipmentPrimaryKey)
               .Skip((query.PageIndex - 1) * query.PageSize)
               .Take(query.PageSize)
               .ToList();

            // 利用继承关系，直接实例化APIPaging并填充数据
            APIPaging<EquipmentLedger> res = new APIPaging<EquipmentLedger>
            {
                TotalCount = totalCount,
                TotalPage = (int)Math.Ceiling(totalCount / (double)query.PageSize),
                Data = data,
                Code = 100,
                Message = "查询成功"
            };
            return res;
        }

        /// <summary>
        /// 新增设备台账
        /// </summary>
        /// <param name="equipment">设备台账实体</param>
        /// <returns>新增成功返回1，失败返回0</returns>
        public async Task<int> AddEquipmentAsync(EquipmentLedger equipment)
        {
            try
            {
                var result = await baseRepository.AddAsync(equipment);
                return result > 0 ? 1 : 0;
            }
            catch (Exception ex)
            {
                // 这里可以记录日志，比如使用NLog、Serilog等日志框架
                Console.WriteLine($"新增设备台账失败: {ex.Message}");
                return 0;
            }
        }

        /// <summary>
        /// 根据id删除设备台账
        /// </summary>
        /// <param name="id">设备台账id</param>
        /// <returns>删除成功返回1，失败返回0</returns>
        public async Task<int> DeleteEquipmentAsync(int id)
        {
            try
            {
                var result = await baseRepository.DeleteAsync(id);
                return result > 0 ? 1 : 0;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"删除设备台账失败: {ex.Message}");
                return 0;
            }
        }

        /// <summary>
        /// 根据多个id批量删除设备台账
        /// </summary>
        /// <param name="ids">设备台账id列表</param>
        /// <returns>删除成功的数量</returns>
        public async Task<int> DeleteEquipmentsAsync(List<int> ids)
        {
            int count = 0;
            try
            {
                foreach (var id in ids)
                {
                    var result = await baseRepository.DeleteAsync(id);
                    if (result > 0)
                    {
                        count++;
                    }
                }
                return count;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"批量删除设备台账失败: {ex.Message}");
                return count;
            }
        }

        /// <summary>
        /// 获取所有设备台账
        /// </summary>
        /// <returns>设备台账列表</returns>
        public async Task<List<EquipmentLedger>> GetAllEquipmentsAsync()
        {
            try
            {
                var queryable = baseRepository.GetAll();
                return await queryable.ToListAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取所有设备台账失败: {ex.Message}");
                return new List<EquipmentLedger>();
            }
        }

        /// <summary>
        /// 根据id获取设备台账
        /// </summary>
        /// <param name="id">设备台账id</param>
        /// <returns>设备台账实体，如果不存在返回null</returns>
        public async Task<EquipmentLedger> GetEquipmentByIdAsync(int id)
        {
            try
            {
                return await baseRepository.FindAsync(id);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"根据id获取设备台账失败: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 获取设备台账的列信息（这里假设仓储接口有相关方法获取列信息，实际需根据仓储接口具体实现调整）
        /// </summary>
        /// <returns>列信息列表，这里暂返回空列表</returns>
        public async Task<List<object>> GetEquipmentColumnsAsync()
        {
            try
            {
                // 这里需要根据实际仓储接口实现来获取列信息
                return new List<object>();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取设备台账列信息失败: {ex.Message}");
                return new List<object>();
            }
        }

        /// <summary>
        /// 根据条件筛选获取设备台账
        /// </summary>
        /// <param name="name">设备名称（可选）</param>
        /// <param name="code">设备编码（可选）</param>
        /// <param name="status">设备状态（可选）</param>
        /// <returns>筛选后的设备台账列表</returns>
        public async Task<List<EquipmentLedger>> GetFilteredEquipmentsAsync(string name = null, string code = null, int? status = null)
        {
            try
            {
                Expression<Func<EquipmentLedger, bool>> expression = e => true;
                if (!string.IsNullOrEmpty(name))
                {
                    expression = expression.AndAlso(e => e.EquipmentName.Contains(name));
                }
                if (!string.IsNullOrEmpty(code))
                {
                    expression = expression.AndAlso(e => e.EquipmentCode.Contains(code));
                }
                if (status.HasValue)
                {
                    expression = expression.AndAlso(e => e.Status == status.Value);
                }
                var queryable = baseRepository.GetAll(expression);
                return await queryable.ToListAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"筛选设备台账失败: {ex.Message}");
                return new List<EquipmentLedger>();
            }
        }

        /// <summary>
        /// 更新列的可见性（这里假设仓储接口有相关方法支持更新列可见性，实际需根据仓储接口具体实现调整）
        /// </summary>
        /// <param name="columnName">列名</param>
        /// <param name="isVisible">是否可见</param>
        /// <returns>无返回值，成功执行方法，失败可记录日志</returns>
        public async Task UpdateColumnVisibilityAsync(string columnName, bool isVisible)
        {
            try
            {
                // 这里根据实际仓储接口实现来更新列可见性
            }
            catch (Exception ex)
            {
                Console.WriteLine($"更新列可见性失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 更新设备台账
        /// </summary>
        /// <param name="equipment">设备台账实体</param>
        /// <returns>更新成功返回1，失败返回0</returns>
        public async Task<int> UpdateEquipmentAsync(EquipmentLedger equipment)
        {
            try
            {
                var result = await baseRepository.UpdateAsync(equipment);
                return result > 0 ? 1 : 0;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"更新设备台账失败: {ex.Message}");
                return 0;
            }
        }
    }

    // 扩展方法，用于组合Expression<Func<T, bool>>
    public static class ExpressionExtensions
    {
        public static Expression<Func<T, bool>> AndAlso<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
        }
    }
}